package com.zty.service;

import com.zty.config.DiscoveryConfig;
import com.zty.util.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Author ZTY
 * @Description 当服务启动起来后主动进行注册，并且会主动地定时发送心跳
 * @Date 17:08 2023-12-23
 **/

@Service
@Slf4j
public class Actuator {

    @Value("${server.port}")
    private int port;

    @Value(("${discovery.server-host}"))
    private String metaHost;

    @Value(("${discovery.server-port}"))
    private int metaPort;

    //  该服务器的基础信息从配置中拿
    private final DiscoveryConfig discoveryConfig;

    private final RestTemplate restTemplate;

    private final ScheduledExecutorService scheduledExecutorService;


    public Actuator(DiscoveryConfig discoveryConfig, RestTemplate restTemplate, ScheduledExecutorService scheduledExecutorService) {
        this.discoveryConfig = discoveryConfig;
        this.restTemplate = restTemplate;
        this.scheduledExecutorService = scheduledExecutorService;
    }

    @PostConstruct
    public void register() throws Exception {
        String serverAddress = discoveryConfig.getServerAddress();

        //  参数构造
        String hostAddress = RequestUtil.getLocalHostExactAddress().toString();

        Map<String, Object> params = new HashMap<>();
        params.put("serviceId",discoveryConfig.getServiceId());
        params.put("host",hostAddress);
        params.put("port",port);
        params.put("schema",discoveryConfig.getSchema());

        //  调用一个http请求，从当前地址带上参数去和Meta做注册
        Map result = restTemplate.postForObject(discoveryConfig.getServerAddress() + "/register",
                                                params, Map.class);

        log.info("{}",result);

        //  判断是否注册成功
        if (Objects.isNull(result) || !result.get("code").equals(200)){
            throw new RuntimeException("服务注册失败");
        }

        //  若注册成功，则启用定时任务发送心跳包
        scheduledExecutorService.scheduleAtFixedRate(()->{
            //  定时发送心跳包(put方式)
            restTemplate.put(discoveryConfig.getServerAddress() + "/heartbeat", params);
            log.info("{}给{}发送了一次心跳包",hostAddress + ":" + port,metaHost+ ":" +metaPort);
        },0,10, TimeUnit.SECONDS);

    }
}
